home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of MacTutor - S…e Code for Volumes 1 to 5
/
The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin
/
Source Code
/
#46 (Jul 89)
/
MacTutor Edit Extender
/
EditExtender.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-06-08
|
12KB
|
604 lines
/*
Edit Extender Desk Accessory
for MacTutor Magazine
June 1, 1988
by Joel McNamara, Satori Software
*/
/* the required stuff... */
#include "EventMgr.h"
#include "MenuMgr.h"
#include "MemoryMgr.h"
#include "FontMgr.h"
#include "FileMgr.h"
#include "DeviceMgr.h"
#include "DialogMgr.h"
#include "IntlPkg.h"
#include "StdFilePkg.h"
/* the globals... */
int ALREADY_OPEN = 0;
int CONDITION = 0;
int RUNCODE = 0;
DCtlPtr DCE;
GrafPtr SAVEPORT;
MenuHandle THE_MENUHANDLE;
/* the constants... */
/* this routine returns the correct resource number for the driver */
#define RsrcID(id) (0xC000 + (~DCE->dCtlRefNum << 5) + id)
/* the dialogs */
#define AboutDLOG 0
#define CountsDLOG 1
#define MessageDLOG 2
/* counts DITL items */
#define CharItem 2
#define WordsItem 3
#define SentenceItem 4
#define ParagraphItem 5
/* the fake window */
#define FakeWIND 0
/* run code commands */
#define UpperCaseCOND 1
#define LowerCaseCOND 2
#define ReverseCaseCOND 3
#define CapitalizeCOND 4
#define CountsCOND 5
#define TextCOND 6
#define DateCOND 7
#define TimeCOND 8
/* STR# error messages */
#define ListSTR 0
#define MemoryMSG 1
#define GenericMSG 2
#define CreateMSG 3
#define OpenMSG 4
#define WriteMSG 5
#define SelectMSG 6
/* menu items */
#define AboutITEM 1
#define UpperITEM 3
#define LowerITEM 4
#define ReverseITEM 5
#define CapitalITEM 6
#define DateITEM 8
#define TimeITEM 9
#define CountsITEM 11
#define TextITEM 13
#define QuitITEM 15
/* DA messages */
#define OpenMessage 0
#define ControlMessage 2
#define CloseMessage 4
/* let's start... */
main(controlParam, dControl, message)
cntrlParam *controlParam;
DCtlPtr dControl;
short message;
{
EvQEl tempQElement;
if ((dControl->dCtlStorage) == 0) {
SysBeep(5);
if (message == OpenMessage) {
SysBeep(5);
Display(MemoryMSG);
CloseDriver(dControl->dCtlRefNum);
}
return(0);
}
DCE = dControl;
switch (message) {
case OpenMessage:
DoOpen();
break;
case ControlMessage:
switch (controlParam->csCode) {
/* who needs to be in control */
case accRun:
if ((RUNCODE != 0) && (OSEventAvail(keyDownMask,
&tempQElement) == 0))
DoRuncode(RUNCODE);
break;
case accMenu:
DoMenu(controlParam->csParam[1]);
break;
case goodBye:
DoGoodBye();
break;
}
break;
case CloseMessage:
DoClose();
break;
}
return(0);
}
/* open the DA */
DoOpen()
{
DCE->dCtlFlags |= dNeedLock|dNeedGoodBye|dCtlEnable|dNeedTime;
DCE->dCtlDelay = 15;
DCE->dCtlMenu = RsrcID(0);
if (ALREADY_OPEN)
return;
RUNCODE = 0;
ALREADY_OPEN = 1;
THE_MENUHANDLE = GetMenu( DCE->dCtlMenu);
(*THE_MENUHANDLE)->menuID = DCE->dCtlMenu;
InsertMenu(THE_MENUHANDLE,0);
DrawMenuBar();
}
/* handle any menu items */
DoMenu(theItem)
int theItem;
{
switch (theItem)
{
case AboutITEM:
DoAbout();
break;
case UpperITEM:
DoCopy();
CONDITION = UpperCaseCOND;
break;
case LowerITEM:
DoCopy();
CONDITION = LowerCaseCOND;
break;
case ReverseITEM:
DoCopy();
CONDITION = ReverseCaseCOND;
break;
case CapitalITEM:
DoCopy();
CONDITION = CapitalizeCOND;
break;
case DateITEM:
SetRuncode();
CONDITION = DateCOND;
break;
case TimeITEM:
SetRuncode();
CONDITION = TimeCOND;
break;
case CountsITEM:
DoCopy();
CONDITION = CountsCOND;
break;
case TextITEM:
DoCopy();
CONDITION = TextCOND;
break;
case QuitITEM:
DoClose();
break;
default:
break;
}
HiliteMenu(0);
}
/* about us */
DoAbout()
{
DialogPtr theDialog;
int dummy;
theDialog = GetNewDialog(RsrcID(AboutDLOG),0,-1);
ModalDialog(0, &dummy);
DisposDialog(theDialog);
}
/* close everything up */
DoClose()
{
DeleteMenu(DCE->dCtlMenu);
DisposeMenu(THE_MENUHANDLE);
ALREADY_OPEN = 0;
DCE->dCtlMenu = 0;
DCE->dCtlWindow = 0;
DrawMenuBar();
}
/* good bye... */
DoGoodBye()
{
DCE->dCtlMenu = 0;
DCE->dCtlWindow = 0;
}
/* do a control c */
DoCopy()
{
struct keys{
long charCode;
long modifiers;
} *keysPtr;
long len;
GetPort(&SAVEPORT);
len = ZeroScrap();
keysPtr = (struct keys*)0x174;
keysPtr->charCode = 0x00000000;
keysPtr->modifiers = 0x00008000;
PostEvent(3,67);
keysPtr->charCode = 0x00000000;
keysPtr->modifiers = 0x00000000;
RUNCODE = 1;
}
/* get the DA's attention */
SetRuncode()
{
RUNCODE = 1;
}
/* handle any run codes */
DoRuncode(myRunCode)
short myRunCode;
{
switch (myRunCode)
{
case 1: /* bring up the dummy window */
DCE->dCtlWindow = GetNewWindow(RsrcID(FakeWIND),0,-1);
((WindowPeek)(DCE->dCtlWindow))->windowKind = DCE->dCtlRefNum;
SetPort(DCE->dCtlWindow);
RUNCODE = 2;
break;
case 2: /* do a paste event */
PostPaste();
RUNCODE = 3;
break;
case 3: /* now deal with our commands */
DoText();
break;
default:
break;
}
}
/* here's where we do our edit commands */
DoText()
{
long len;
long myOffset;
long loop;
long temp;
long theSecs;
Handle myHandle;
Handle newHandle;
Handle theHandle;
Rect itemRect;
int sentences;
int paragraphs;
int words;
int chars;
int itemType;
int tempInt;
char myChar;
char prevChar;
DialogPtr theDialog;
Ptr myPtr;
Str255 numStr;
Str255 timeStr;
RUNCODE = 0;
myHandle = NewHandle(0);
len = GetScrap(myHandle,'TEXT',&myOffset);
if ((len <= 0) && (CONDITION <= CapitalizeCOND))
/* nothing's in the scrap */
{
SysBeep(5);
Display(SelectMSG);
DisposeWindow(DCE->dCtlWindow);
DCE->dCtlWindow = 0;
SetPort(SAVEPORT);
}
else
{
if (CONDITION < CountsCOND)
/* do we need a handle for manipulation? */
newHandle = NewHandle(GetHandleSize(myHandle));
switch (CONDITION)
{
/* the upper routine */
case UpperCaseCOND:
for (loop = 0; loop <= (GetHandleSize(myHandle)); loop++)
*(((char *)(*newHandle)) + loop) = toupper(*((char *)((long)(*myHandle) + loop)));
break;
/* the lower case routine */
case LowerCaseCOND:
for (loop = 0; loop <= (GetHandleSize(myHandle)); loop++)
*((char *)((long)(*newHandle) + loop)) = tolower(*((char *)((long)(*myHandle) + loop)));
break;
/* the reverse case routine */
case ReverseCaseCOND:
for (loop = 0; loop <= (GetHandleSize(myHandle)); loop++) {
if (isupper(*((char *)((long)(*myHandle) + loop))))
*((char *)((long)(*newHandle) + loop)) = tolower(*((char *)((long)(*myHandle) + loop)));
else
if (islower(*((char *)((long)(*myHandle) + (long)loop))))
*((char *)((long)(*newHandle) + loop)) = toupper(*((char *)((long)(*myHandle) + loop)));
else
*((char *)((long)(*newHandle) + loop)) = *((char *)((long)(*myHandle) + loop));
}
break;
/* the capitalization routine */
case CapitalizeCOND:
prevChar = (char)'x';
for (loop = 0; loop <= (GetHandleSize(myHandle)); loop++)
{
if (loop == 0)
{
*((char *)((long)(*newHandle) + loop)) = toupper(*((char *)((long)(*myHandle) + loop)));
prevChar = *((char *)((long)(*newHandle) + loop));
}
else
{
if ((prevChar == ' ') || (prevChar == '\r') ||
(prevChar == '\t'))
*((char *)((long)(*newHandle) + loop)) = toupper(*((char *)((long)(*myHandle) + loop)));
else
*((char *)((long)(*newHandle) + loop)) = *((char *)((long)(*myHandle) + loop));
prevChar = *((char *)((long)(*newHandle) + loop));
}
}
break;
/* a simplistic wc */
case CountsCOND:
chars = sentences = paragraphs = words = 0;
myPtr = *myHandle;
for (temp = 0; temp <= len; temp++)
{
myChar = *((char *)((long)myPtr + temp));
chars++;
if (myChar == '\r')
paragraphs++;
if (myChar == '.' || myChar == '!' || myChar == '?')
sentences++;
if (myChar == ' ' || myChar == '\t' || myChar == '\r')
words++;
}
InitCursor();
theDialog = GetNewDialog(RsrcID(CountsDLOG),0,-1);
SetPort(theDialog);
NumToString(chars - paragraphs,numStr);
GetDItem(theDialog,CharItem,&itemType,&theHandle,&itemRect);
SetIText(theHandle,numStr);
NumToString(words,numStr);
GetDItem(theDialog,WordsItem,&itemType,&theHandle,&itemRect);
SetIText(theHandle,numStr);
NumToString(sentences,numStr);
GetDItem(theDialog,SentenceItem,&itemType,&theHandle,&itemRect);
SetIText(theHandle,numStr);
NumToString(paragraphs,numStr);
GetDItem(theDialog,ParagraphItem,&itemType,&theHandle,&itemRect);
SetIText(theHandle,numStr);
ModalDialog(0,&tempInt);
CloseDialog(theDialog);
break;
/* text to save condition */
case TextCOND:
Extract(myHandle);
break;
/* display date condition */
case DateCOND:
GetDateTime(&theSecs);
IUDateString(theSecs,longDate,&timeStr);
PtoCstr(timeStr);
ZeroScrap();
PutScrap(strlen(timeStr),'TEXT',&timeStr);
PostPaste();
break;
/* display time condition */
case TimeCOND:
GetDateTime(&theSecs);
IUTimeString(theSecs,TRUE,&timeStr);
PtoCstr(timeStr);
ZeroScrap();
PutScrap(strlen(timeStr),'TEXT',&timeStr);
PostPaste();
break;
default:
break;
}
DisposeWindow(DCE->dCtlWindow);
DCE->dCtlWindow = 0;
SetPort(SAVEPORT);
if (CONDITION < CountsCOND)
/* then we need to paste in the new stuff */
{
ZeroScrap();
PutScrap(GetHandleSize(myHandle),'TEXT',*newHandle);
DisposHandle(newHandle);
PostPaste();
}
}
DisposHandle(myHandle);
CONDITION = 0;
}
/* do a paste event */
PostPaste()
{
struct keys{
long charCode;
long modifiers;
} *keysPtr;
keysPtr = (struct keys*)0x174;
keysPtr->charCode = 0x00000000;
keysPtr->modifiers = 0x00008000;
PostEvent(3,86);
keysPtr->charCode = 0x00000000;
keysPtr->modifiers = 0x00000000;
}
/* error message display */
Display(theIndex)
int theIndex;
{
DialogPtr theDialog;
int dummy;
Str255 theMessage;
GetIndString(&theMessage,RsrcID(ListSTR),theIndex);
InitCursor();
theDialog = GetNewDialog(RsrcID(MessageDLOG),0,-1);
ParamText(theMessage,"\p","\p","\p");
ModalDialog(0,&dummy);
DisposDialog(theDialog);
}
/* save selected text to a file */
Extract(myHandle)
Handle myHandle;
{
SFReply myReply;
Point myLoc;
int errCode, refNum;
long theCount;
myLoc.v = 90;
myLoc.h = 90;
HLock(myHandle);
SFPutFile(myLoc,"\pSave selected text to:","\pUntitled",0L,&myReply);
if (myReply.good)
{
errCode = Create(myReply.fName,myReply.vRefNum,'EDIT','TEXT');
if (errCode != noErr);
{
if (errCode == dupFNErr) {
FSDelete(myReply.fName,myReply.vRefNum);
errCode = Create(myReply.fName,myReply.vRefNum,'EDIT','TEXT');
}
else if (errCode != noErr) {
Display(CreateMSG);
HUnlock(myHandle);
return;
}
}
if (FSOpen(myReply.fName,myReply.vRefNum,&refNum) != noErr) {
Display(OpenMSG);
FSClose(refNum);
HUnlock(myHandle);
return;
}
theCount = GetHandleSize(myHandle);
if (FSWrite(refNum,&theCount,*myHandle) != noErr) {
Display(WriteMSG);
FSClose(refNum);
HUnlock(myHandle);
return;
}
FSClose(refNum);
}
HUnlock(myHandle);
}
/* just in case your compiler doesn't already have these...
otherwise, leave them out... */
strlen(s)
register char *s;
{
char *s0 = s;
while (*s++);
return (s-s0-1);
}
int toupper(c)
char c;
{
return((c>='a') && (c<='z') ? (c-32) : c);
}
int tolower(c)
char c;
{
return((c>='A') && (c<='Z') ? (c+32) : c);
}
int isupper(c)
char c;
{
return((c>='A') && (c<='Z'));
}
int islower(c)
char c;
{
return((c>='a') && (c<='z'));
}